<?php
/**
 *                    _ooOoo_
 *                   o8888888o
 *                   88" . "88
 *                   (| -_- |)
 *                    O\ = /O
 *                ____/`---'\____
 *              .   ' \\| |// `.
 *               / \\||| : |||// \
 *             / _||||| -:- |||||- \
 *               | | \\\ - /// | |
 *             | \_| ''\---/'' | |
 *              \ .-\__ `-` ___/-. /
 *           ___`. .' /--.--\ `. . __
 *        ."" '< `.___\_<|>_/___.' >'"".
 *       | | : `- \`.;`\ _ /`;.`/ - ` : | |
 *         \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 *                    `=---='
 *
 * .............................................
 *          佛祖保佑             永无BUG
 */

namespace App\Service;


use App\Exceptions\AdminErrorException;
use App\Exceptions\WechatException;
use EasyWeChat\Core\Exceptions\RuntimeException;
use EasyWeChat\Support\XML;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;

class WechatBankCard
{
    protected $app;
    protected $http;
    protected $url = 'https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank';

    public function __construct()
    {
        $this->app = app('wechat');

       $this->http = new Client();
    }
    public function toBankCard(array $params)
    {
        foreach (['bank_code', 'partner_trade_no', 'enc_bank_no', 'enc_true_name', 'amount'] as $key) {
            if (empty($params[$key])) {
                throw new AdminErrorException(\sprintf('"%s" is required.', $key));
            }
        }

        $publicKey = file_get_contents(\Config::get('wechat.payment.public_path'));
        $params['mch_id']=\Config::get('wechat.payment.merchant_id');
        $params['nonce_str']=uniqid();
        $params['enc_bank_no'] = $this->rsa_public_encrypt($params['enc_bank_no'], $publicKey);
        $params['enc_true_name'] = $this->rsa_public_encrypt($params['enc_true_name'], $publicKey);
        $params['sign']=$this->generate_sign($params,\Config::get('wechat.payment.key'),'md5');
        $options=[];
        $options = array_merge([
            'cert' => \Config::get('wechat.payment.cert_path'),
            'ssl_key' =>  \Config::get('wechat.payment.key_path'),
        ], $options);
        $options = array_merge([
            'body' => XML::build($params),
        ], $options);
         $response=$this->http->post($this->url,
             $options);
        $response1=$this->toArray($response);
        if($response1['result_code']=="FAIL"){
            throw  new WechatException($response1['err_code_des']);
        }
        return $response1;
    }
    public function toArray($response)
    {
        $content = $response->getBody()->getContents();;

        if (false !== stripos($response->getHeaderLine('Content-Type'), 'xml') || 0 === stripos($content, '<xml')) {
            return XML::parse($content);
        }

        $array = json_decode($content, true);

        if (JSON_ERROR_NONE === json_last_error()) {
            return (array) $array;
        }

        return [];
    }
    public function outTradeNo()
    {
        mt_srand((double)microtime() * 1000000);
        return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
    }
    protected function rsa_public_encrypt($content,$publicKey){
        $encrypted = '';

        openssl_public_encrypt($content, $encrypted, openssl_pkey_get_public($publicKey), OPENSSL_PKCS1_OAEP_PADDING);
        return base64_encode($encrypted);
    }
    protected  function generate_sign(array $attributes, $key, $encryptMethod = 'md5')
    {
        ksort($attributes);

        $attributes['key'] = $key;

        return strtoupper(call_user_func_array($encryptMethod, [urldecode(http_build_query($attributes))]));
    }
}